<?php

namespace app\apijson\controller;

use support\BaseResponse;
use support\Request;
use app\apijson\core\ApiJsonFactory;
use app\apijson\config\EncryptionConfig;
use app\exception\ExpressException;
use app\service\ApijsonDebugService;

/**
 * 加密APIJSON控制器
 * 用于前端调用，支持JSON数据加密传输
 */
class EncryptedApiController
{
    /**
     * 获取加密密钥
     */
    private function getEncryptionKey(): string
    {
        return EncryptionConfig::getEncryptionKey();
    }

    /**
     * 获取加密方法
     */
    private function getCipherMethod(): string
    {
        return EncryptionConfig::getCipherMethod();
    }

    /**
     * 处理加密的Get请求
     */
    public function encryptedGet(Request $request)
    {
        return $this->handleEncryptedRequest($request, 'get');
    }


    /**
     * 处理加密请求的核心方法
     */
    private function handleEncryptedRequest(Request $request, string $method)
    {
        $startTime = microtime(true);
        $requestId = ApijsonDebugService::generateRequestId();
        
        // 获取用户信息
        $userInfo = ApijsonDebugService::getUserInfo(
            $request->header(),
            $request->getRealIp(),
            $request->header('User-Agent', '')
        );
        
        $originalRequest = [
            'data' => $request->input('data'),
            'space_id' => $request->input('space_id'),
            'region_ids' => $request->input('region_ids'),
        ];
        
        try {
            // 获取加密数据
            $encryptedData = $request->input('data');
            $space_id = $request->input('space_id');
            $region_ids = $request->input('region_ids');

            if ($space_id !== get_space_id()  || $region_ids !== get_region_ids_str()){
                return admin_abort("数据错误");
            }
            
            if (!$encryptedData) {
                return admin_abort("缺少加密数据");
            }
            
            // 解密数据
            $decryptedJson = $this->decrypt($encryptedData);
            if (!$decryptedJson) {
                return admin_abort("数据解密失败");
            }
            
            // 解析JSON
            $jsonData = json_decode($decryptedJson, true);
            if (json_last_error() !== JSON_ERROR_NONE) {
                $errorMsg = 'JSON格式错误: ' . json_last_error_msg();
                
                // 记录解析错误
                ApijsonDebugService::logParseError(
                    $requestId,
                    $originalRequest,
                    $errorMsg,
                    $request->header(),
                    $request->path(),
                    $userInfo
                );

                return admin_abort($errorMsg);
            }
            
            var_dump("json解析为", $jsonData);
            
            // 调用APIJSON处理
            $result = ApiJsonFactory::query($jsonData, $method);
            
            // 记录成功执行的调试信息
            $executionTime = (int)((microtime(true) - $startTime) * 1000);
            $memoryUsage = memory_get_peak_usage(true);
            
            $requestData = ApijsonDebugService::createRequestData(
                $requestId,
                $originalRequest,
                $jsonData,
                $request->header(),
                $request->path(),
                $userInfo
            );
            
            $responseData = ApijsonDebugService::createResponseData(
                $result,
                ApijsonDebugService::extractSqlQueries($result),
                ApijsonDebugService::calculateRecordCount($result),
                true
            );
            
            $executionInfo = ApijsonDebugService::createExecutionInfo($executionTime, $memoryUsage);
            
            ApijsonDebugService::logDebugInfo($requestData, $responseData, $executionInfo);
            
            // 直接返回明文结果，不加密
            return BaseResponse::ok(data: $result, msg: '请求成功');

        } catch (ExpressException $e) {
            // 记录异常信息
            $executionTime = (int)((microtime(true) - $startTime) * 1000);
            $memoryUsage = memory_get_peak_usage(true);
            
            $requestData = ApijsonDebugService::createRequestData(
                $requestId,
                $originalRequest,
                [],
                $request->header(),
                $request->path(),
                $userInfo
            );
            
            $responseData = ApijsonDebugService::createResponseData(
                [],
                [],
                0,
                false,
                $e->getMessage(),
                (string)$e->getCode()
            );
            
            $executionInfo = ApijsonDebugService::createExecutionInfo($executionTime, $memoryUsage);
            
            ApijsonDebugService::logDebugInfo($requestData, $responseData, $executionInfo);
            
            return BaseResponse::fail(msg: $e->getMessage(), code: $e->getCode() ?: 400);
        } catch (\Exception $e) {
            // 记录系统异常信息
            $executionTime = (int)((microtime(true) - $startTime) * 1000);
            $memoryUsage = memory_get_peak_usage(true);
            
            $requestData = ApijsonDebugService::createRequestData(
                $requestId,
                $originalRequest,
                [],
                $request->header(),
                $request->path(),
                $userInfo
            );
            
            $responseData = ApijsonDebugService::createResponseData(
                [],
                [],
                0,
                false,
                $e->getMessage(),
                '500'
            );
            
            $executionInfo = ApijsonDebugService::createExecutionInfo($executionTime, $memoryUsage);
            
            ApijsonDebugService::logDebugInfo($requestData, $responseData, $executionInfo);
            
            return BaseResponse::fail(msg: '服务器内部错误: ' . $e->getMessage(), code: 500);
        }
    }

    /**
     * 加密数据
     */
    private function encrypt(string $data): string
    {
        $iv = random_bytes(16);
        $encrypted = openssl_encrypt($data, $this->getCipherMethod(), $this->getEncryptionKey(), 0, $iv);
        return base64_encode($iv . $encrypted);
    }

    /**
     * 解密数据
     */
    private function decrypt(string $encryptedData): string|false
    {
        $aesResult = $this->decryptAES($encryptedData);
        if ($aesResult !== false) {
            return $aesResult;
        }

//        $base64Result = $this->decryptBase64($encryptedData);
//        if ($base64Result !== false) {
//            return $base64Result;
//        }

        return false;
    }

    /**
     * AES解密
     */
    private function decryptAES(string $encryptedData): string|false
    {
        try {
            $data = base64_decode($encryptedData);
            if ($data === false) {
                return false;
            }

            // 检查数据长度是否足够
            if (strlen($data) < 16) {
                return false;
            }

            $iv = substr($data, 0, 16);
            $encrypted = substr($data, 16);
            
            $cipherMethod = $this->getCipherMethod();
            $encryptionKey = $this->getEncryptionKey();
            
            // 尝试使用OpenSSL解密
            $result = openssl_decrypt($encrypted, $cipherMethod, $encryptionKey, OPENSSL_RAW_DATA, $iv);
            
            if ($result === false) {
                $errors = openssl_error_string();
                while ($errors !== false) {
                    $errors = openssl_error_string();
                }
                return false;
            }

            return $result;
        } catch (\Exception $e) {
            return false;
        }
    }


    /**
     * 生成加密密钥（用于配置）
     */
    public static function generateKey(): string
    {
        return EncryptionConfig::generateKey();
    }
}
